package testes;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Enumeration;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class EditableTree extends JFrame {
	
	private static class Node extends DefaultMutableTreeNode {

		Element element;

		public Node(Element e) {
			this.element = e;
		}
		
		public Node(String nome) {
			this.element = new Element(nome);
		}
		
		
		public Element getElement() {
			return element;
		}

		@Override
		public String toString() {
			return  element.getName()  + " "
					+ ( element.getText() != null ?  element.getText() : "" ) 
					+ ( element.getAttribute("nome") != null ? "nome=" + element.getAttribute("nome").getValue() : "" )    
					+ ( element.getAttribute("restricao") != null ? ", restricao=" + element.getAttribute("restricao").getValue() : "" );
		}

	}	
	

  private Node m_rootNode = new Node(new Element("meta.sctipt"));

  private DefaultTreeModel m_model = new DefaultTreeModel(m_rootNode);

  private JTree m_tree = new JTree(m_model);

  private JButton m_addButton = new JButton("Add Node");

  private JButton m_delButton = new JButton("Delete Node");

  private JButton m_searchButton = new JButton("Search Node");

  private JButton m_searchAndDeleteButton = new JButton("Search and Delete Node");

  private JTextField m_searchText;

  public EditableTree() {
	  
    build("meta.script.tropico_ra.xml");
    
    m_tree.setEditable(true);
    m_tree.setSelectionRow(0);

    JScrollPane scrollPane = new JScrollPane(m_tree);
    getContentPane().add(scrollPane, BorderLayout.CENTER);

    JPanel panel = new JPanel();

    m_addButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Node selNode = (Node) m_tree.getLastSelectedPathComponent();
        if (selNode == null) {
          return;
        }
        Node newNode = new Node("New Node");
        m_model.insertNodeInto(newNode, selNode, selNode.getChildCount());

        TreeNode[] nodes = m_model.getPathToRoot(newNode);
        TreePath path = new TreePath(nodes);
        m_tree.scrollPathToVisible(path);
        m_tree.setSelectionPath(path);
        m_tree.startEditingAtPath(path);
      }
    });
    panel.add(m_addButton);

    m_delButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Node selNode = (Node) m_tree.getLastSelectedPathComponent();
        removeNode(selNode);
      }
    });
    panel.add(m_delButton);

    JPanel searchPanel = new JPanel();
    searchPanel.setBorder(BorderFactory.createEtchedBorder());

    m_searchText = new JTextField(10);
    searchPanel.add(m_searchText);

    m_searchButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        Node node = searchNode(m_searchText.getText());
        if (node != null) {
          TreeNode[] nodes = m_model.getPathToRoot(node);
          TreePath path = new TreePath(nodes);
          m_tree.scrollPathToVisible(path);
          m_tree.setSelectionPath(path);
        } else {
          System.out.println("Node with string " + m_searchText.getText() + " not found");
        }
      }
    });
    searchPanel.add(m_searchButton);

    m_searchAndDeleteButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        DefaultMutableTreeNode node = searchNode(m_searchText.getText());
        if (node != null) {
          removeNode(node);
        } else {
          System.out.println("Node with string " + m_searchText.getText() + " not found");
        }
      }
    });
    searchPanel.add(m_searchAndDeleteButton);
    panel.add(searchPanel);
    getContentPane().add(panel, BorderLayout.SOUTH);
    setSize(700, 400);
    setVisible(true);
  }

  public Node searchNode(String nodeStr) {
    Node node = null;
    Enumeration e = m_rootNode.breadthFirstEnumeration();
    while (e.hasMoreElements()) {
      node = (Node) e.nextElement();
      if (nodeStr.equals(node.getElement().getName())) {
        return node;
      }
    }
    return null;
  }
  
  public void caminhamento(){
	    Node node = null;
	    Enumeration e = m_rootNode.breadthFirstEnumeration();
	    while (e.hasMoreElements()) {
	      node = (Node) e.nextElement();
	      System.out.println(node); 
	    }
  }

  public void removeNode(DefaultMutableTreeNode selNode) {
    if (selNode == null) {
      return;
    }
    MutableTreeNode parent = (MutableTreeNode) (selNode.getParent());
    if (parent == null) {
      return;
    }
    MutableTreeNode toBeSelNode = getSibling(selNode);
    if (toBeSelNode == null) {
      toBeSelNode = parent;
    }
    TreeNode[] nodes = m_model.getPathToRoot(toBeSelNode);
    TreePath path = new TreePath(nodes);
    m_tree.scrollPathToVisible(path);
    m_tree.setSelectionPath(path);
    m_model.removeNodeFromParent(selNode);
  }

  private MutableTreeNode getSibling(DefaultMutableTreeNode selNode) 
  {
    MutableTreeNode sibling = (MutableTreeNode) selNode.getPreviousSibling();
    if (sibling == null) {
      sibling = (MutableTreeNode) selNode.getNextSibling();
    }
    return sibling;
  }
  
  
	public void build(String pathToXml) 
	{
	     SAXBuilder reader = new SAXBuilder();
	     Document doc = null;
		try {
			doc = reader.build(pathToXml);
		} catch (JDOMException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		m_rootNode.removeAllChildren();
		m_rootNode.add(build(doc.getRootElement()));
		m_model.setRoot(m_rootNode);
		
//	    ((DefaultTreeModel) m_tree.getModel()).setRoot(m_rootNode);
//		m_tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
	}

	public Node build(Element e) 
	{
	   Node result = new Node(e);
	   for(Object o : e.getChildren()) {
	      Element child = (Element) o;
	      result.add(build(child));
	   }
	   return result;         
	}

  public static void main(String[] arg) 
  {
    EditableTree editableTree = new EditableTree();
  }
  
  
  
  
}
